package com.yugao.fintech.antelope.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yugao.fintech.antelope.auth.assembly.AuthAssembly;
import com.yugao.fintech.antelope.auth.mapper.AuthLoginLogMapper;
import com.yugao.fintech.antelope.auth.model.AuthLoginLog;
import com.yugao.fintech.antelope.auth.model.mq.LoginLogMQ;
import com.yugao.fintech.antelope.auth.model.rqrs.log.LoginLogPageReq;
import com.yugao.fintech.antelope.auth.service.AuthLoginLogService;
import com.yugao.fintech.antelope.base.model.constants.UserCons;
import com.yugao.fintech.antelope.system.constants.LogCons;
import com.yugao.fintech.framework.mybatisplus.utils.PageUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuthLoginLogServiceImpl implements AuthLoginLogService {
    @Autowired
    private AuthLoginLogMapper loginLogMapper;
    @Autowired
    private AuthAssembly authAssembly;

    /**
     * 新增系统登录日志
     */
    @Override
    public boolean save(LoginLogMQ.MsgPayload req) {
        // 封装对象
        AuthLoginLog entity = authAssembly.toLoginLog(req);
        // 目前统一设置成内网
        entity.setLocation("内网ip");
        // 日志状态
        if (UserCons.Oauth.LOGIN_SUCCESS.equals(req.getStatus()) || UserCons.Oauth.LOGOUT.equals(req.getStatus())) {
            entity.setStatus(LogCons.Status.SUCCESS);
        } else if (UserCons.Oauth.LOGIN_FAIL.equals(req.getStatus())) {
            entity.setStatus(LogCons.Status.FAIL);
        }
        return loginLogMapper.insert(entity) > 0;
    }

    @Override
    public IPage<AuthLoginLog> pageLoginLog(LoginLogPageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<AuthLoginLog> lqw = Wrappers.<AuthLoginLog>lambdaQuery()
                .like(StringUtils.isNotEmpty(req.getUserName()), AuthLoginLog::getUserName, req.getUserName())
                .eq(StringUtils.isNotEmpty(req.getStatus()), AuthLoginLog::getStatus, req.getStatus())
                .le(Objects.nonNull(endTime), AuthLoginLog::getLoginTime, endTime)
                .ge(Objects.nonNull(beginTime), AuthLoginLog::getLoginTime, beginTime)
                .orderByDesc(AuthLoginLog::getLoginTime);
        return loginLogMapper.selectPage(PageUtil.to(req), lqw);
    }

    /**
     * 查询系统登录日志集合
     *
     * @param req 访问日志对象
     * @return 登录记录集合
     */
    @Override
    public List<AuthLoginLog> list(LoginLogPageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<AuthLoginLog> lqw = Wrappers.<AuthLoginLog>lambdaQuery()
                .like(StringUtils.isNotEmpty(req.getUserName()), AuthLoginLog::getUserName, req.getUserName())
                .eq(StringUtils.isNotEmpty(req.getStatus()), AuthLoginLog::getStatus, req.getStatus())
                .ge(Objects.nonNull(beginTime), AuthLoginLog::getLoginTime, beginTime)
                .le(Objects.nonNull(endTime), AuthLoginLog::getLoginTime, endTime)
                .orderByDesc(AuthLoginLog::getLoginTime);
        return loginLogMapper.selectList(lqw);
    }

    /**
     * 批量删除系统登录日志
     *
     * @param infoIds 需要删除的登录日志ID
     */
    @Override
    public boolean deleteBatch(Long[] infoIds) {
        return loginLogMapper.deleteBatchIds(Arrays.stream(infoIds).collect(Collectors.toList())) == infoIds.length;
    }

    /**
     * 清空系统登录日志
     */
    @Override
    public void clear() {
        loginLogMapper.delete(new LambdaQueryWrapper<>());
    }

    @Override
    public void deleteOfDaysBefore(Integer daysBefore) {
        if (Objects.isNull(daysBefore)) {
            return;
        }
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        instance.add(Calendar.DAY_OF_YEAR, daysBefore * -1);
        LambdaQueryWrapper<AuthLoginLog> wrapper = Wrappers.<AuthLoginLog>lambdaQuery()
                .le(AuthLoginLog::getLoginTime, instance.getTime());
        loginLogMapper.delete(wrapper);
    }
}
